﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ERF;
using Microsoft.Xna.Framework;
using ERF.Physics;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Audio;

namespace FirstPerson.Objects.Weapons
{
    /// <summary>
    /// Represents an AK47 machine gun.
    /// </summary>
    class AK47 : RayWeapon
    {
        private SoundEffect fireSound;
        private const float FIRE_RATE = 66; // Miliseconds between each shot. Approx. 15 bullets per second.
        private float time = 0;
        private float xMovementFactor = 0.01f; // The speed factor of the weapons movement on the x-axis.
        private float yMovementFactor = 0.02f; // The speed factor of the weapons movement on the y-axis.
        private float lastShot = FIRE_RATE;
        
        private Vector3 previousLightDirection;
        private bool lightDirChanged;

        /// <summary>
        /// Creates a new instance of AK47.
        /// </summary>
        /// <param name="game">The game this instance belongs to.</param>
        /// <param name="holder">The player that is the holder of this weapon.</param>
        public AK47(ERFGame game, Player holder)
            : base(game, holder, "Models\\Weapons\\AK47\\AK47", new Vector3(-9f, 148f, 12f),  1000)
        {
            base.weaponId = WeaponId.AK47;
            base.scale = new Vector3(10f);
            base.effect.SpecularMap = game.Content.Load<Texture2D>("Models\\Weapons\\AK47\\AK47_specular");
            base.effect.EnableSpecularMap = true;
            base.effect.SpecularIntensity = 0.6f;

            this.fireSound = game.Content.Load<SoundEffect>("Sounds\\AK47");
            this.emptySound = game.Content.Load<SoundEffect>("Sounds\\generic_empty");

            this.Ammunition = 30;
        }

        public override void Update(GameTime gameTime, ref Matrix world) {
            if (base.isShooting) {
                this.lastShot += (float)gameTime.ElapsedGameTime.TotalMilliseconds;
                if (this.lastShot >= FIRE_RATE) {
                    this.lastShot -= FIRE_RATE;

                    if (this.Ammunition > 0)
                    {
                        this.Ammunition--;
                        base.Shoot();

                        // Changes the light source and intensity on the weapon.
                        base.effect.AmbientIntensity = 1.5f;

                        if (!this.lightDirChanged)
                        {
                            this.previousLightDirection = base.effect.LightDirection;
                            base.effect.LightDirection = base.holder.World.Backward;
                            this.lightDirChanged = true;
                        }
                        this.Play3DSound(fireSound);
                    }
                }
                else {
                    // Changes the light source and intensity back to default.
                    if (this.lightDirChanged) {
                        base.effect.LightDirection = this.previousLightDirection;
                        base.effect.AmbientIntensity = 0.4f;
                        this.lightDirChanged = false;
                    }
                }
            }
            else {
                // Changes the light source and intensity back to default.
                if (this.lightDirChanged) {
                    base.effect.LightDirection = this.previousLightDirection;
                    base.effect.AmbientIntensity = 0.4f;
                    this.lightDirChanged = false;
                }
            }
            this.UpdateWeaponMovement(gameTime);

            base.Update(gameTime, ref world);
        }

     
        /// <summary>
        /// Updates the movement of the weapon.
        /// </summary>
        /// <param name="gameTime"></param>
        private void UpdateWeaponMovement(GameTime gameTime)
        {
            
            if (base.holder.IsMoving)
            {
                this.time += (float)gameTime.ElapsedGameTime.TotalMilliseconds;
                this.position =
                    this.PositionOffset +
                    new Vector3(
                        (float)(Math.Sin(this.time * xMovementFactor)),
                        (float)((Math.Sin(this.time * yMovementFactor)) * 0.4f),
                        0);
            }
        }

        public override short Damage {
            get { return 10; }
        }
    }
}
